﻿# -*- coding: utf-8-*-
import datetime
import time
import traceback
import re
from datetime import datetime
from datetime import timedelta
from openerp import models, api, SUPERUSER_ID, _
from openerp.osv import osv, fields, orm
"""
门店三个二级菜单顺序：上门自提、门店提货记录、财务统计 上门自提里面的菜单就一个：门店下单，这个上门自提的卡券兑换新建时的页面只要输入卡券号码和密码

，点击保存，系统验证卡券号码和密码是否正确、是否激活、是否没有被禁用，然后保存兑换记录，写入财务信息，增加这个门店的应付款，这里的应付金额应
该需要在产品表中增加一个“补助费用”字段来事先维护好，如果补助费用为0说明没有维护过，保存对话记录时抛出例外提示操作失败补助费用为0无法兑换
"""


class apply_delivery(osv.osv):
    _name = 'apply.delivery'
    _rec_name = 'copy_code'
    _inherit = ['mail.thread', 'ir.needaction_mixin']

    def on_change_ship(self, cr, uid, ids, shipping_type, shipping_code, context=None):
        ''' 输入了快递方式即认为已在送货中 '''
        # if shipping_type and (not shipping_code):
        #     raise osv.except_osv(u'警告',u'请填写快递单号')
        # if shipping_code and (not shipping_type):
        #     raise osv.except_osv(u'警告',u'请填写快递方式')
        if shipping_type or shipping_code:
            return {'value': {'is_shipping': True}}
        else:
            return {'value': {'is_shipping': False}}
        # 快递单号和快递方式，只要有一个输入，另外一个必填

    def on_change_code_password(self, cr, uid, ids, copy_code, password, context=None):
        ''' 将输入的卡券号码转为卡券记录的id，并验证是否可以提货,然后验证用户名和密码是否匹配 '''
        # 若券号未输入，直接报错
        if not copy_code:
            if not password:
                return {}
            return {'warning': {'title': u'错误', 'message': u'请先输入卡券显示号码'}}

        card_line_id = self.pool['product.card.line'].search(
            cr, SUPERUSER_ID, [('code', '=', copy_code)], context=context)
        if card_line_id:
            card_line_id = card_line_id[0]  # 取输入券号的第一个id，转成int型
        else:
            return {'warning': {'title': u'错误', 'message': u'卡券号码不存在！'},
                    'value': {'password': '', 'copy_code': "",'is_vip':'' }}
        card_line = self.pool['product.card.line'].browse(
            cr, SUPERUSER_ID, card_line_id, context=context)
        if card_line.product_id.subsidy_costs == 0.0:
            user = self.pool.get("res.users").browse(
                cr, uid, uid, context=context)
            partners_map = user[0]._company_partner_id([uid], None, None, context=context)
            partner = self.pool.get("res.partner").browse(
                cr, uid, partners_map[uid], context=context)
            if user[0].has_group('dzx_ext.group_stores') and partner.category_id.name != '直营门店':
                return {'warning': {'title': u'错误', 'message': card_line.product_id.name + u'卡券号的产品补助费用没有设置，不可提货！'},
                        'value': {'copy_code': "", 'password': "",'is_vip':''}}
        # 先验证券号，如果验证失败报错，并清空券号和密码
        warning_msg = ''
        if not card_line_id:
            return {'warning': {'title': u'错误', 'message': copy_code + u'卡券号不存在'},
                    'value': {'copy_code': "", 'password': "",'is_vip':''}}
        if not card_line.is_enabled:
            return {'warning': {'title': u'错误', 'message': copy_code + u'卡券未被启用'},
                    'value': {'copy_code': "", 'password': ""}}
        if card_line.level_one_partner_id.name:
            agent_name = u'卡券所属的代理商是' + card_line.level_one_partner_id.name
        else:
            agent_name = u''
        if not card_line.is_active:
            return {'warning': {'title': u'错误', 'message': copy_code + u'卡券未被激活 \n ' + agent_name},
                    'value': {'copy_code': "", 'password': ""}}
        if card_line.is_exchanged:
            return {'warning': {'title': u'错误', 'message': copy_code + u'卡券已被兑换'},
                    'value': {'copy_code': "", 'password': ""}}

        # 如果输入了密码，验证是否与券号匹配
        order_card_id = self.pool.get('order.card').search(
            cr, SUPERUSER_ID, [('starting_number_copy', '<=', card_line.code), ('ending_number', '>=', card_line.code)
                ,('picking_id.picking_type_code','=','outgoing'),('is_active','=',False)], order='shipped_date asc', context=context)
        shipped_date = False
        second_sale_time = False
        if order_card_id:
            # raise osv.except_osv(u'错误', u"卡券未售出过")
            order_card_obj = self.pool.get('order.card').browse(
                cr, 1, order_card_id, context=context)
            shipped_date = order_card_obj[0].shipped_date
            if len(order_card_id)>1:
                second_sale_time = order_card_obj[1].shipped_date
        if password:
            # 只有管理员有密码表的读取权限

            if not self.pool['product.card.password'].search(cr, SUPERUSER_ID,
                                                             [('line_id', '=', card_line_id),
                                                              ('password', '=', password)],
                                                             context=context):
                return {'warning': {'title': u'错误', 'message': u"卡券号和密码不匹配"},
                        'value': {'password': ""}}
            # 只有券号和密码都输入了且匹配，才填充卡券id字段
            return {'value': {'code': card_line_id, 'product_name': card_line.product_id,
                              'card_owner_id': card_line.owner_id, 'fisrt_time_sale': shipped_date,
                              'is_vip': card_line.is_vip,'second_sale_time':second_sale_time}}
        else:
            return {'value': {'product_name': card_line.product_id, 'card_owner_id': card_line.owner_id,
                              'fisrt_time_sale': shipped_date, 'is_vip': card_line.is_vip,'second_sale_time':second_sale_time}}

    def action_move_line(self, cr, uid, vals, assigned_shop_id, context=None):
        ''' 门店代发货后记录应收总部的补助费用和快递费用'''
        user_obj = self.pool.get('res.users')
        move_obj = self.pool.get('account.move')
        user = user_obj.browse(
            cr, SUPERUSER_ID, assigned_shop_id, context=context)
        card_line = self.pool['product.card.line'].browse(
            cr, SUPERUSER_ID, vals.get('code'), context=context)
        subsidy_costs = vals.get('subsidy_costs', False)
        if not subsidy_costs:
            product = self.pool["product.product"].browse(
                cr, SUPERUSER_ID, card_line.product_id.id, context=context)
            subsidy_costs = product.subsidy_costs
        # 只针对门店用户做此处理，总部发货无需补助
        # 根据当前日期取的默认期间
        period_id = self.pool['account.move'].default_get(
            cr, SUPERUSER_ID, ['period_id'], context=context).get('period_id', False)
        # 费用凭证类型
        journal_id = self.pool["account.journal"].search(cr, SUPERUSER_ID, [(
            'type', '=', 'purchase'), ('company_id', '=', user.company_id.id)], context=context)
        journal = self.pool["account.journal"].browse(
            cr, SUPERUSER_ID, journal_id, context=context)
        # 创建会计凭证，这里用管理员身份创建，避免权限问题
        move_id = move_obj.create(cr, SUPERUSER_ID, {
            'journal_id': journal.id,
        }, context=context)
        # 借方：代发货补助，，采购分录对应的默认借方科目，产品里的补助费用
        self.pool["account.move.line"].create(cr, SUPERUSER_ID, {
            'name': u'%s代发货' % (card_line.code),
            'account_id': journal.default_debit_account_id.id,
            'debit': subsidy_costs,
            'journal_id': journal.id,
            'date': time.strftime("%Y-%m-%d"),
            'period_id': period_id,
            'move_id': move_id,
        }, context=context)
        # 贷方： 代发货补助 ，门店业务伙伴，门店业务伙伴对应的应付科目，产品里的补助费用
        self.pool["account.move.line"].create(cr, SUPERUSER_ID, {
            'name': u'%s代发货' % (card_line.code),
            'partner_id': user.partner_id.id,
            'account_id': user.partner_id.property_account_payable.id,
            'credit': subsidy_costs,
            'journal_id': journal.id,
            'date': time.strftime("%Y-%m-%d"),
            'period_id': period_id,
            'move_id': move_id,
        }, context=context)
        return_vals = {'move_id': move_id, 'subsidy': subsidy_costs}
        # 如果需要快递送货
        if (vals.get('shipping_type', False) and vals.get('shipping_code', False)):
            return_vals.update(self.create_shop_express_fee(
                cr, uid, card_line.code, assigned_shop_id, move_id, context=context))
        if not context.get('delay'):
            move_obj.button_validate(cr, SUPERUSER_ID, [move_id], context)
        return return_vals

    def create_shop_express_fee(self, cr, uid, code, assigned_shop_id, move_id=None, context=None):
        # 生成运费补助
        user_obj = self.pool.get('res.users')
        move_obj = self.pool.get('account.move')
        user = user_obj.browse(
            cr, SUPERUSER_ID, assigned_shop_id, context=context)
        # 只针对门店用户做此处理，总部发货无需补助
        # 根据当前日期取的默认期间
        period_id = self.pool['account.move'].default_get(
            cr, SUPERUSER_ID, ['period_id'], context=context).get('period_id', False)
        # 费用凭证类型
        journal_id = self.pool["account.journal"].search(cr, SUPERUSER_ID, [(
            'type', '=', 'purchase'), ('company_id', '=', user.company_id.id)], context=context)
        journal = self.pool["account.journal"].browse(
            cr, SUPERUSER_ID, journal_id, context=context)
        shop_express_fee_id = self.pool.get("ir.config_parameter").search(cr, uid,
                                                                          [('key', '=', 'shop_express_fee')], context=context)
        # 系统参数，管理员应该不会去删掉它
        shop_express_fee = self.pool.get("ir.config_parameter").browse(
            cr, uid, shop_express_fee_id, context=context)[0].value
        new_move_id_flag = False
        if not move_id:
            move_id = move_obj.create(cr, SUPERUSER_ID, {
                'journal_id': journal.id,
            }, context=context)
            new_move_id_flag = True

        self.pool["account.move.line"].create(cr, SUPERUSER_ID, {
            'name': u'%s代发货运费' % (code),
            'account_id': journal.default_debit_account_id.id,
            'debit': shop_express_fee,
            'journal_id': journal.id,
            'date': time.strftime("%Y-%m-%d"),
            'period_id': period_id,
            'move_id': move_id,
        }, context=context)
        self.pool["account.move.line"].create(cr, SUPERUSER_ID, {
            'name': u'%s代发货运费' % (code),
            'partner_id': user.partner_id.id,
            'account_id': user.partner_id.property_account_payable.id,
            'credit': shop_express_fee,
            'journal_id': journal.id,
            'date': time.strftime("%Y-%m-%d"),
            'period_id': period_id,
            'move_id': move_id,
        }, context=context)
        if new_move_id_flag:
            move_obj.button_validate(cr, SUPERUSER_ID, [move_id], context)
        return {'shop_express_fee': shop_express_fee}

    def create(self, cr, uid, vals, context=None):
        if not vals.get('code', False):
            raise osv.except_osv(u'错误', u"请先输入卡券显示号码")
        track_obj = self.pool.get('product.card.track')
        card_line = self.pool['product.card.line'].browse(
            cr, SUPERUSER_ID, vals.get('code'), context=context)
        self.get_estimated_ship_date(cr, uid, vals.get(
            'estimated_ship_date'), context=context)
        apply_delivery_obj = self.search(cr, uid, [('code', '=', vals.get(
            'code')), ('is_canceled', '=', True)], context=context)
        if apply_delivery_obj:
            osv.osv.unlink(self, cr, SUPERUSER_ID,
                           apply_delivery_obj, context=context)
        # 如果是门店自提记录，并且勾选了【需要送货】，get_is_shipping表示客户到门店上门自提
        # if vals.get('is_need_delivery',False):
        #     get_is_shipping=False
        # else:
        shop_express_subsidy = {}
        get_is_need_delivery = self.default_get(
            cr, uid, ['is_need_delivery'], context=context).get('is_need_delivery', False)
        if not card_line.is_exchanged:
            card_line.write({'is_exchanged': True})
            track_obj.create(cr, uid, {'card_line_id': card_line.id,
                                       'code': card_line.code,
                                       'changed_field': u'是否兑换',
                                       'old_value': u'未兑换',
                                       'new_value': u'已兑换',
                                       'operation_type': 'exchange',
                                       })
        else:
            raise osv.except_osv(u'错误', u"卡券已被兑换")
        if not vals.get('is_need_delivery', True) or (vals.get('shipping_type', False) and vals.get('shipping_code', False)):
            if context.get("default_is_shop_accept") and context.get("default_assigned_shop_id"):
                shop_express_subsidy = self.action_move_line(
                    cr, uid, vals, context.get("default_assigned_shop_id"), context=context)
            vals.update({'is_shipping': True, "shop_express_fee": shop_express_subsidy.get(
                'shop_express_fee', 0), "subsidy": shop_express_subsidy.get('subsidy', 0)})

        #取得第一次铺券时间
        order_card_id = self.pool.get('order.card').search(
            cr, uid, [('starting_number_copy', '<=', card_line.code), ('ending_number', '>=', card_line.code)], limit=1, order='shipped_date asc', context=context)
        shipped_date = False
        if order_card_id:
            #    raise osv.except_osv(u'错误', u"卡券未售出过")
            order_card_obj = self.pool.get('order.card').browse(
                cr, uid, order_card_id, context=context)
            shipped_date = order_card_obj.shipped_date
        #取得最后激活日期
        cr.execute(
            "SELECT oc.shipped_date FROM order_card oc INNER JOIN sale_order so ON so.id=oc.order_id  "
            " WHERE oc.is_active=TRUE AND oc.starting_number_copy <= %s AND oc.ending_number >= %s "
            " AND so.is_return=FALSE ORDER BY oc.shipped_date DESC LIMIT 1", (card_line.code, card_line.code))
        active_order_code_row = cr.dictfetchone()
        active_shipped_date = None
        if active_order_code_row:
            active_shipped_date = active_order_code_row.get('shipped_date')
        #else: 因为有13年14年卡券的提货，无法提供激活日期
        #    raise osv.except_osv(u'错误', u"卡券未查到激活订单，无法提货")

        vals.update({'copy_code': card_line.code,'publish_date':card_line.publish_date,
                     'client_name': card_line.owner_id.short_name, 'fisrt_time_sale': shipped_date,
                     'first_active_date': active_shipped_date})
        return super(apply_delivery, self).create(cr, uid, vals, context=context)

    def write(self, cr, uid, ids, vals, context=None):
        moves = []
        for delivery in self.browse(cr, uid, ids, context=context):
            if vals.get('estimated_ship_date'):
                self.get_estimated_ship_date(cr, uid, vals.get(
                    'estimated_ship_date'), context=context)
            # 如果已经分配门店并且门店已接受
            if delivery.assigned_shop_id and delivery.is_shop_accept:
                # 如果有填写或导入快递方式和快递单号，并且没有发货状态，则给予产品和运费补助
                if (vals.get('shipping_type', False) and vals.get('shipping_code', False)) and not delivery.is_shipping:
                    # 设为已发货
                    vals.update(
                        {'code': delivery.code.id, 'is_shipping': True})
                    # if  context.get("default_is_shop_accept") and
                    # context.get("default_assigned_shop_id"):
                    shop_express_subsidy = self.action_move_line(
                        cr, uid, vals, delivery.assigned_shop_id.id, context=context)
                    moves.append(shop_express_subsidy.get('move_id', []))
                    vals.update({"shop_express_fee": shop_express_subsidy.get(
                        'shop_express_fee', 0), "subsidy": shop_express_subsidy.get('subsidy', 0)})
                # 如果已经发货，并且之后修改补充了快递单号和快递方式，则给予运费补助（之前已经给了产品补助）
                if delivery.is_shipping and (vals.get('shipping_type', False) and vals.get('shipping_code', False)) and delivery.shop_express_fee == 0:
                    vals.update(self.create_shop_express_fee(
                        cr, uid, delivery.copy_code, delivery.assigned_shop_id.id, None, context=context))
        super(apply_delivery, self).write(cr, uid, ids, vals, context)
        return moves

    def onchange_province(self, cr, uid, ids, county, city, province, context=None):
        # 为地址填写时方便，当选定省时 ，市区的列表里面只有所选省的
        if province:
            if city:
                city_obj = self.pool.get('all.city').browse(
                    cr, uid, [city], context=context)
                if city_obj[0].province_name.id == province:
                    if county:
                        county_obj = self.pool.get('all.country').browse(
                            cr, uid, [county], context=context)
                        if county_obj.city_name.id == city:
                            return{}
                    return {'domain': {'city': [('province_name', '=', province)]}, 'value': {'country': ''}}
                else:
                    return {'domain': {'city': [('province_name', '=', province)]}, 'value': {'city': ''}}
            else:
                return {'domain': {'city': [('province_name', '=', province)]}}
        else:
            return {'domain': {'city': [], 'country': []}, 'value': {'country': '', 'city': ''}}

    def onchange_country(self, cr, uid, ids, county, city, province, context=None):
        # 选定了一个区县，自动填充其所属的省和市
        if county:
            try:
                county_obj = self.pool.get('all.country').browse(
                    cr, uid, [county], context=context)
                city_obj = self.pool.get('all.city').browse(
                    cr, uid, county_obj[0].city_name.id, context=context)
                return {'domain': {'country': [('city_name', '=', city)]}, 'value': {'city': county_obj[0].city_name.id, 'province': city_obj[0].province_name.id}}
            except Exception, ex:
                raise osv.except_osv(u'错误', u"无法根据所选区县填充省和市")

    def onchange_city(self, cr, uid, ids, county, city, province, context=None):
        # 为地址填写时方便，当选定市时 ，县区的列表里面只有所选市的
        if city:
            city_obj = self.pool.get('all.city').browse(
                cr, uid, [city], context=context)
            province_id = city_obj[0].province_name
            if not province:
                if county:
                    county_obj = self.pool.get('all.country').browse(
                        cr, uid, [county], context=context)
                    if county_obj[0].city_name.id == city:
                        return {'domain': {'country': [('city_name', '=', city)]}}
                    return {'value': {'country': "", 'province': province_id}, 'domain': {'country': [('city_name', '=', city)]}}
                return {'value': {'province': province_id}, 'domain': {'country': [('city_name', '=', city)]}}
            else:
                if county:
                    county_obj = self.pool.get('all.country').browse(
                        cr, uid, [county], context=context)
                    if county_obj.city_name.id == city:
                        if province_id.id != province:
                            return {'domain': {'country': [('city_name', '=', city)], 'city': [('province_name', '=', province_id.id)]}, 'value': {'province': province_id}}
                        return {'domain': {'country': [('city_name', '=', city)], 'city': [('province_name', '=', province_id.id)]}}
                    else:
                        if province_id.id != province:
                            return {'domain': {'country': [('city_name', '=', city)], 'city': [('province_name', '=', province_id.id)]}, 'value': {'province': province_id.id, 'country': ""}}
                        return {'domain': {'country': [('city_name', '=', city)], 'city': [('province_name', '=', province_id.id)]}, 'value': {'country': ""}}
                else:
                    if province_id.id != province:
                        return {'domain': {'country': [('city_name', '=', city)], 'city': [('province_name', '=', province_id.id)]}, 'value': {'province': province_id.id}}
                    return {'domain': {'country': [('city_name', '=', city)], 'city': [('province_name', '=', province_id.id)]}}
        else:
            return {'domain': {'country': []}, 'value': {'country': ""}}

    def check_phone(self, cr, uid, ids, context=None):
        '''验证手机号输入是都规范'''
        for apply_delivery in self.browse(cr, uid, ids, context=context):
            if apply_delivery.to_name:
                if apply_delivery.mobile_number or apply_delivery.phone_number:
                    p2 = re.compile('\d{11}')
                    if apply_delivery.mobile_number and (not p2.match(apply_delivery.mobile_number)):
                        return False
                    return True
                else:
                    return False
            else:
                return True

    def get_estimated_ship_date(self, cr, uid, estimated_ship_date='', context=None):
        user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
        now = datetime.now()

        # 如果没传字段estimated_ship_date的值，则函数给字段estimated_ship_date设置默认值
        if not estimated_ship_date:
            return (now + timedelta(days=2)).strftime('%Y-%m-%d')
        # 缓冲期,默认发货日期
        if user[0].has_group('dzx_ext.group_call_center_director'):
            buffer_days = 0
        else:
            buffer_days = 2
        estimated_date = now + timedelta(days=buffer_days)
        default_estimated_date = estimated_date.strftime('%Y-%m-%d')

        # 从系统参数中获取卡券提货起始和结束日期
        estimated_ship_start_date_id = self.pool.get("ir.config_parameter").search(
            cr, uid, [('key', '=', 'estimated_ship_start_date')], context=context)
        start_date = self.pool.get("ir.config_parameter").browse(
            cr, uid, estimated_ship_start_date_id, context=context)[0].value
        estimated_ship_end_date_id = self.pool.get("ir.config_parameter").search(
            cr, uid, [('key', '=', 'estimated_ship_end_date')], context=context)
        end_date = self.pool.get("ir.config_parameter").browse(
            cr, uid, estimated_ship_end_date_id, context=context)[0].value

        #如果用户非呼叫中心管理员，则进行提货日期校验
        if not user[0].has_group('dzx_ext.group_call_center_director'):
            # 默认发货日期超出提货截止日期
            if default_estimated_date > end_date:
                raise osv.except_osv(u'错误', u"%d天后超出提货结束日期%s" %
                                     (buffer_days, end_date))
            # 输入的日期超出提货截止日期
            if estimated_ship_date > end_date:
                raise osv.except_osv(u'错误', u'预计发货日期最晚要在 %s' % end_date)

            # 输入的日期在提货开始日期前，则推后到开始日期和默认发货日期这两个日期较大的一个
            if estimated_ship_date < max(default_estimated_date, start_date):
                raise osv.except_osv(u'错误', u'预计发货日期至少要在 %s' %
                                     max(default_estimated_date, start_date))
        return

    def accept_button(self, cr, uid, ids, context=None):
        '''门店中总部分配待接受的卡券需要确定'''
        accept_ids = []
        for accept in self.browse(cr, uid, ids, context=context):
            if not accept.is_shop_accept:
                accept_ids.append(accept.id)
            else:
                raise osv.except_osv(u'错误', u'提货记录已接受，不可以重新接受！')
            if accept.assigned_shop_id.id != uid:
                raise osv.except_osv(u'错误', u'本条提货记录可能重新分配了，请刷新后再操作。！')
        self.write(cr, uid, accept_ids, {'is_shop_accept': True,
                                         'shop_accept_datetime': time.strftime("%Y-%m-%d", time.localtime(time.time())),
                                         }, context=context)
        return True

    def export_data(self, cr, uid, ids, fields_to_export, raw_data=False, context=None):
        '''记录哪些记录已经导出过'''
        self.write(cr, uid, ids, {'is_export': True}, context=context)
        return super(apply_delivery, self).export_data(cr, uid, ids, fields_to_export, raw_data, context=context)

    # 取得快递详情html
    def _get_express_detail_html(self, cr, uid, ids, field_name=None, arg=None, context=None):
        res = dict.fromkeys(ids, '')
        for apply_delivery in self.browse(cr, uid, ids, context=context):
            if apply_delivery['shipping_type'] and apply_delivery['shipping_code']:
                express_type_name = apply_delivery['shipping_type']['name']
                express_type_com = apply_delivery[
                    'shipping_type']['description']
                html = """<div>
                            <table border="0" cellpadding="0" cellspacing="0" class="oe_form_group"><tr>
                            <td><span class="oe_form_field">快递类型:%s</span></td>
                            <td><span class="oe_form_field">快递单号:%s</span></td></tr></table>
                            <button class="btn btn-normal" onclick="query_express_detail(this)">查询物流详情</button>
                            <div id="express-delivery-detail" data-shipping-type="%s" data-shipping-code="%s"></div>
                        </div>""" % (express_type_name, apply_delivery['shipping_code'],
                                     express_type_com, apply_delivery['shipping_code'])
                #<img src="/web/static/src/img/throbber.gif" width="16" height="16"/>
                res[apply_delivery.id] = html
            else:
                res[apply_delivery.id] = u'未发货'
        return res

    # 重载openerp的复制功能,提醒用户使用“复制”按钮
    def copy(self, cr, uid, id, default=None, context=None):
        raise osv.except_osv(u'警告', u'该复制功能有错误，请点击界面上的“复制”按钮！')

    # 弹出delivery.copy.wizard窗口,替代原本的复制功能
    def copy_button(self, cr, uid, id, default=None, context=None):
        return {
            'type': 'ir.actions.act_window',
            'res_model': 'delivery.copy.wizard',
            'view_mode': 'form',
            'view_type': 'form',
            'name': u'提货记录复制向导',
            'target': 'new',
            'context': {'delivery_id_copied': id},
        }

    _columns = {
        'code': fields.many2one('product.card.line', u'卡券', required=False, copy=False),
        'copy_code': fields.char(u'卡券显示号码', copy=False),
        # 怎么两个产品字段，这个product_id只在一个view上用过，是否应该删除？
        'card_owner_id': fields.related('code', 'owner_id', type='many2one', relation='res.partner', string='卡券归属方', readonly=True, store=True, copy=False),
        'product_id': fields.related('code', 'product_id', type='many2one', relation='product.product', string='产品ID', readonly=True, store=True, copy=False),
        'product_name': fields.related('code', 'product_id', type='many2one', relation='product.product', string='产品名称', readonly=True, store=True, copy=False),
        'assigned_shop_id': fields.many2one('res.users', u'被分配到门店编号', copy=False),
        'is_shop_accept': fields.boolean(u'门店已接受', copy=False),
        'shop_accept_datetime': fields.date(u'门店接受时间', copy=False, track_visibility='always'),
        'province': fields.many2one('res.country.state', u'省', domain=u"[('country_id.name','=','中国')]"),
        'city': fields.many2one('all.city', u'市'),
        'country': fields.many2one('all.country', u'县区'),
        'address': fields.char(u'街道地址', size=64),
        'postal_code': fields.char(u'邮编', size=64),
        # 当此字段有变更下方有提示消息
        'to_name': fields.char(u'姓名', size=64, track_visibility='always'),
        'ship_memo': fields.text(u'送货备注'),
        'mobile_number': fields.char(u'手机号码 ', size=64, track_visibility='always'),
        'phone_number': fields.char(u'电话号码', size=64, track_visibility='always'),
        'estimated_ship_date': fields.date(u'期望发货日期', track_visibility='always'),
        'shipping_code': fields.char(u'快递单号', size=64, copy=False),
        'password': fields.char(u'卡券密码', size=64, copy=False),
        'shipping_type': fields.many2one('express.type', u'快递方式', copy=False),
        'is_shipping': fields.boolean(u'发货中', size=64, copy=False, track_visibility='always'),
        'is_need_delivery': fields.boolean(u'快递送货', size=64, copy=False),
        'is_export': fields.boolean(u'是否已导出', copy=False),
        'openid': fields.char(u'微信账号openid', copy=False),
        'express_detail_html': fields.function(_get_express_detail_html, string=u'快递详情', type='html', method=True, readonly=True),
        'client_name': fields.char(string=u'渠道', copy=False),
        'subsidy': fields.float(string=u'产品补助费', copy=False),
        'shop_express_fee': fields.float(string=u'门店补助运费', copy=False),
        'is_canceled': fields.boolean(u'是否取消', copy=False),
        'fisrt_time_sale': fields.date(u'第一次铺券时间'),
        'publish_date': fields.datetime(u'卡券发行日期'),
        'second_sale_time': fields.date(u'第二次铺券时间'),
        'is_vip': fields.selection([(True,u'是')],u'是否VIP'),
        'first_active_date': fields.date(u'第一次激活日期')
    }
    _defaults = {
        'estimated_ship_date': lambda self, cr, uid, context=None: self.get_estimated_ship_date(cr, uid, context=context),
        'is_need_delivery': True,
    }
    # def default_get(self, cr, uid, fields, context=None):
    #     res = super(apply_delivery, self).default_get(cr, uid, fields, context=context)
    #     user=self.pool.get('res.users').browse(cr,uid,uid,context=context)
    #     shop_accept_datetime=self.get_estimated_ship_date(cr,uid,context=context)
    #     if user:
    # 门店用户创建的记录，自动分配给自己，如非快递送货，直接勾选发货中
    #         if user[0].has_group('dzx_ext.group_stores') and not user[0].has_group('dzx_ext.group_call_center'):
    #             res.update({'assigned_shop_id':user[0].id,
    #                         'is_shop_accept':True,
    #                         'shop_accept_datetime':shop_accept_datetime,
    #                         })
    #         else:
    # 否则是总部创建的，肯定需要发货
    #             res.update({'is_need_delivery': True})
    #     return res
    _constraints = [(check_phone, u'\n请输入正确的手机号码或者电话号码，两个不能都为空', [
                     'mobile_number', 'phone_number'])]
    _sql_constraints = [
        ('code_apply_uniq', 'unique(copy_code)', '同一张卡券号只能有一个提货记录!')
    ]

    def cancel_apply_delivery(self, cr, uid, ids, context=None):
        apply_delivery_obj = self.browse(cr, uid, ids, context=context)
        user_objs = self.pool.get('res.users').browse(
            cr, uid, uid, context=context)

        if apply_delivery_obj.assigned_shop_id.id and apply_delivery_obj.is_shipping:
            raise osv.except_osv(u'错误', u"提货记录已分配给门店并且已发货，不可取消提货记录!")
        if apply_delivery_obj.is_export and not user_objs[0].has_group('dzx_ext.group_call_center'):
            raise osv.except_osv(u'错误', u"提货记录已导出, 不可取消提货记录!")

        self.write(cr, uid, ids, {'is_canceled': True}, context=context)
        card_line = self.pool['product.card.line'].browse(
            cr, SUPERUSER_ID, apply_delivery_obj.code.id, context=context)
        card_line.write({'is_exchanged': False})
        track_obj = self.pool.get('product.card.track')
        track_obj.create(cr, uid, {'card_line_id': card_line.id,
                                   'code': card_line.code,
                                   'changed_field': u'是否兑换',
                                   'old_value': u'已兑换',
                                   'new_value': u'未兑换',
                                   'operation_type': 'exchange',
                                   })
        return True

# 提货记录复制向导


class delivery_copy_wizard(osv.osv_memory):
    _name = 'delivery.copy.wizard'

    # 按下“确认“按钮之后，将输入的卡券号、密码与需要复制的数据一起生成新的记录。
    def confirm_button(self, cr, uid, ids, context=None):
        # 从context中获取相关信息
        delivery_id = context['delivery_id_copied'][0]
        # 获取除了卡号和密码之外的数据
        copy_data = self.pool.get('apply.delivery').copy_data(
            cr, uid, delivery_id, default=None, context=context)
        apply_deliverys = self.pool.get('apply.delivery').browse(
            cr, uid, delivery_id, context=context)[0]

        if apply_deliverys.assigned_shop_id.id == uid:
            copy_data.update({'assigned_shop_id': uid, 'is_shop_accept': True,
                              'shop_accept_datetime': time.strftime('%Y-%m-%d'), 'estimated_ship_date': (datetime.now() + timedelta(days=2)).strftime('%Y-%m-%d')})
        new_id = []
        wizard_obj = self.browse(cr, uid, ids, context=context)
        if wizard_obj[0].delivery_record:
            for line in wizard_obj[0].delivery_record:
                tmp = copy_data.copy()
                card_line_ids = self.pool['product.card.line'].search(
                    cr, SUPERUSER_ID, [('code', '=', line.copy_code)], context=context)
                data = dict({'code': card_line_ids[
                            0], 'copy_code': line.copy_code, "is_need_delivery": True}, **tmp)
                new_id.append(self.pool.get(
                    'apply.delivery').create(cr, uid, data, context))
            return {
                'type': 'ir.actions.act_window',
                'res_model': 'apply.delivery',
                'view_mode': 'tree,form',
                'view_type': 'form',
                'domain': "[('id','in',[" + ','.join(map(str, new_id)) + "])]",
            }

    _columns = {
        'delivery_record': fields.one2many('delivery.copy.line', 'name', required=False, help=u'对应向导记录明细'),
    }

# 提货记录复制向导的明细


class delivery_copy_line(osv.osv_memory):
    _name = 'delivery.copy.line'

    def on_change_value(self, cr, uid, ids, copy_code, password, context=None):
        if copy_code:
            if not self.pool.get('apply.delivery').search(cr, uid, [('copy_code', '=', copy_code), ('is_canceled', '=', False)], context=context):
                res = self.pool.get('apply.delivery').on_change_code_password(
                    cr, uid, ids, copy_code, password, context=context)
                return res
            else:
                return {'warning': {'title': u'错误', 'message': u'同一张卡券号只能有一个提货记录'}}

    _columns = {
        'name': fields.many2one('delivery.copy.wizard'),
        #'code':fields.many2one('product.card.line',u'卡券',required=False),
        'copy_code': fields.char(u'卡券号码', required=True),
        'password': fields.char(u'卡券密码', size=64, required=True),
    }
